package top.songxs.gmall.item.testcontroller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@RestController
@Slf4j
@RequestMapping("hello")
public class HelloController {
    @Autowired
    StringRedisTemplate redisTemplate;
    public static final String key = "keyCount";

    @GetMapping("count")
    public void test() {
        String uuid = UUID.randomUUID().toString().replace("-", "");

        try {
            lock(uuid);
            biz();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            unlock(uuid);
        }

    }

    public String lock(String uuid) {

        while (redisTemplate.opsForValue().setIfAbsent(key, uuid, 30, TimeUnit.SECONDS)) {
        }//给锁设置一个过期时间
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(10);
        pool.scheduleAtFixedRate(()->{
            redisTemplate.expire(key,30,TimeUnit.SECONDS);
        },3,3,TimeUnit.SECONDS);

        return uuid;
    }

    //lua
    public void unlock(String uuid) {
        String script = "if redis.call(\"get\",KEYS[1]) == ARGV[1]\n" +
                "then\n" +
                "    return redis.call(\"del\",KEYS[1])\n" +
                "else\n" +
                "    return 0\n" +
                "end";
        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);

        Long result = redisTemplate.execute(redisScript, Arrays.asList(key), uuid);

        if (result == 0) {
            log.info("锁已经不是你自己的了不能删除！");
        }

    }

    public void biz() {
        redisTemplate.opsForValue().increment("count");
    }
}






















